﻿using System;
using AGG.Transform;
using AGG.Image;
using AGG.VertexSource;
using AGG.UI;

namespace AGG
{
    public class lion : AppWidget
    {
        private AGG.UI.SliderWidget alphaSlider;
        private LionShape lionShape = new LionShape();
        double angle = 0;
        double lionScale = 1.0;
        double skewX = 0;
        double skewY = 0;

        public lion()
        {
            alphaSlider = new UI.SliderWidget(5, 5, 512 - 5, 12);
            AddChild(alphaSlider);
            alphaSlider.ValueChanged += new SliderWidget.ValueChangedEventHandler(alphaSlider_ValueChanged);
            alphaSlider.Transform = Affine.NewIdentity();
            alphaSlider.label("Alpha {0:F3}");
            alphaSlider.value(0.1);
        }

        public override void OnParentChanged()
        {
            DockToEdge(AnchorFlags.All);
        }

        public override string DefaultCaption
        {
            get
            {
                return "AGG Example. Lion";
            }
        }

        public override string Description
        {
            get
            {
                return "Affine transformer, and basic renderers. You can rotate and scale the “Lion” with the"
                    + " left mouse button. Right mouse button adds “skewing” transformations, proportional to the “X” "
                    + "coordinate. The image is drawn over the old one with a cetrain opacity value. Change “Alpha” "
                    + "to draw funny looking “lions”. Change window size to clear the window.";
            }
        }

        public override int DefaultWidth
        {
            get
            {
                return 512;

            }
        }

        public override int DefaultHeight
        {
            get
            {
                return 400;
            }
        }

        void alphaSlider_ValueChanged(object sender, EventArgs e)
        {
            Invalidate();
        }

        public override void OnDraw(Graphics2D graphics2D)
        {
            byte alpha = (byte)(alphaSlider.value() * 255);
            for (int i = 0; i < lionShape.NumPaths; i++)
            {
                lionShape.Colors[i].A_Byte = alpha;
            }

            Affine transform = Affine.NewIdentity();
            transform *= Affine.NewTranslation(-lionShape.Center.x, -lionShape.Center.y);
            transform *= Affine.NewScaling(lionScale, lionScale);
            transform *= Affine.NewRotation(angle + Math.PI);
            transform *= Affine.NewSkewing(skewX / 1000.0, skewY / 1000.0);
            transform *= Affine.NewTranslation(Width / 2, Height / 2);

            // This code renders the lion:
            VertexSourceApplyTransform transformedPathStorage = new VertexSourceApplyTransform(lionShape.Path, transform);
            graphics2D.Render(transformedPathStorage, lionShape.Colors, lionShape.PathIndex, lionShape.NumPaths);

            base.OnDraw(graphics2D);
        }

        void UpdateTransform(double width, double height, double x, double y)
        {
            x -= width / 2;
            y -= height / 2;
            angle = Math.Atan2(y, x);
            lionScale = Math.Sqrt(y * y + x * x) / 100.0;
        }

        protected bool MoveTheLion(MouseEventArgs mouseEvent)
        {
            double x = mouseEvent.X;
            double y = mouseEvent.Y;
            if (mouseEvent.Button == MouseButtons.Left)
            {
                int width = (int)Width;
                int height = (int)Height;
                UpdateTransform(width, height, x, y);
                Invalidate();
                return true;
            }

            if (mouseEvent.Button == MouseButtons.Right)
            {
                skewX = x;
                skewY = y;
                Invalidate();
                return true;
            }

            return false;
        }

        public override void OnMouseDown(MouseEventArgs mouseEvent)
        {
            base.OnMouseDown(mouseEvent);
            
            if (Focused && MouseCaptured)
            {
                if (MouseCaptured)
                {
                    MoveTheLion(mouseEvent);
                }
            }
        }

        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            base.OnMouseMove(mouseEvent);

            if (Focused && MouseCaptured)
            {
                if (MouseCaptured)
                {
                    MoveTheLion(mouseEvent);
                }
            }
        }
    }
}

